package io.gitee.kotle.player.session.impl.exoplayer

import android.content.ComponentName
import android.content.Context
import androidx.core.content.ContextCompat
import androidx.media3.session.MediaBrowser
import androidx.media3.session.SessionToken
import com.google.common.util.concurrent.ListenableFuture

/**
 *
 * 描述：ExoPlayerMediaBrowser
 *
 * @author Jiale.Wei
 *
 * 创建时间：2023/5/5 16:42
 *
 */
abstract class ExoPlayerMediaBrowser : MediaBrowser.Listener {
    private var _browser: MediaBrowser? = null
    private var _isConnecting = false
    private var _browserFuture: ListenableFuture<MediaBrowser>? = null

    /**
     * 监听器集合
     */
    private val callbackList = mutableListOf<Function3<MediaBrowser?, Throwable?, Boolean, Unit>>()

    /**
     * 连接操作
     */
    open fun <T : ExoPlayerMediaService> connect(
        context: Context,
        serviceCls: Class<T>,
        resultCall: (MediaBrowser?, Throwable?, Boolean/*isCache*/) -> Unit
    ) {
        val browser = _browser
        if (browser != null && browser.isConnected) {
            resultCall.invoke(browser, null, true)
            return
        }
        callbackList.add(resultCall)
        if (_isConnecting) {
            return
        }
        _isConnecting = true
        release()
        val sessionToken = SessionToken(context, ComponentName(context, serviceCls))
        val browserFuture = MediaBrowser
            .Builder(context, sessionToken)
            .setListener(this)
            .buildAsync()
        _browserFuture = browserFuture
        browserFuture.addListener({
            try {
                // The session accepted the connection.
                val result = browserFuture.get()
                _browser = result
                onMediaBrowserCreated(result)
                callbackList.forEach {
                    it.invoke(result, null, false)
                }
            } catch (e: Throwable) {
                // The session rejected the connection.
                callbackList.forEach {
                    it.invoke(null, e, false)
                }
            }
            callbackList.clear()
        }, ContextCompat.getMainExecutor(context))
    }

    /**
     * release
     */
    open fun release() {
        _browser?.clearMediaItems()
        _browser?.release()
        _browser = null
        _browserFuture?.let { MediaBrowser.releaseFuture(it) }
        _browserFuture = null
    }

    /**
     * MediaBrowser创建成功
     * 只有第一次创建成功时回调
     */
    open fun onMediaBrowserCreated(browser: MediaBrowser) {

    }
}